package ws

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"github.com/pkg/errors"
	"net/http"
	"sync"
)

var (
	websocketUpgrade = websocket.Upgrader{
		CheckOrigin:     nil,
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
	}
)

type CheckOriginHandler func(r *http.Request) bool
type HandlerFunc func(session *Session, body []byte) (any, error)
type LogicHandler map[string]HandlerFunc
type Manager struct {
	sync.RWMutex
	websocketUpgrade   *websocket.Upgrader
	checkOriginHandler CheckOriginHandler
	ConnectorHandlers  LogicHandler
	clients            map[int]Connection
	ClientReadChan     chan *MsgPack
}

func NewManager(checkOriginHandler CheckOriginHandler, ConnectorHandlers LogicHandler) *Manager {
	return &Manager{checkOriginHandler: checkOriginHandler, ConnectorHandlers: ConnectorHandlers}
}

func (m *Manager) ServeWS(c *gin.Context) error {
	websocketUpgrade.CheckOrigin = m.checkOriginHandler
	wsConn, err := websocketUpgrade.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		return errors.WithStack(fmt.Errorf("websocketUpgrade.Upgrade err:%v", err))
	}
	client := NewClient(wsConn, m)
	m.addClient(client)
	go m.clientReadChanHandler()
	client.Run()
	return nil
}

func (m *Manager) addClient(client *Client) {
	m.Lock()
	defer m.Unlock()
	m.clients[client.Cid] = client
}

func (m *Manager) removeClient(wc *Client) {
	for cid, c := range m.clients {
		if cid == wc.Cid {
			c.Close()
			delete(m.clients, cid)
		}
	}
}

func (m *Manager) clientReadChanHandler() {
	for {
		select {
		case body, ok := <-m.ClientReadChan:
			if ok {
				if ok {
					m.MessageHandler(body)
				}
			}
		}
	}
}

func (m *Manager) Close() {
	for cid, v := range m.clients {
		v.Close()
		delete(m.clients, cid)
	}
}

func (m *Manager) MessageHandler(body *MsgPack) error {

	/*handler, ok := m.ConnectorHandlers[routers[0]]
	if !ok {
		return errors.New("错误的路由")
	}*/
	return nil
}
